/*
 * Title:        CloudSim Toolkit
 * Description:  CloudSim (Cloud Simulation) Toolkit for Modeling and Simulation of Clouds
 * Licence:      GPL - http://www.gnu.org/copyleft/gpl.html
 *
 * Copyright (c) 2009-2012, The University of Melbourne, Australia
 */

package cloudsim.provisioners;

import cloudsim.Vm;

/**
 * BwProvisioner is an abstract class that represents the provisioning policy used by a host
 * to allocate bandwidth (bw) to virtual machines inside it.
 * Each host has to have its own instance of a BwProvisioner.
 * When extending this class, care must be taken to guarantee that
 * the field availableBw will always contain the amount of free bandwidth available for future
 * allocations.
 *
 * @author Rodrigo N. Calheiros
 * @author Anton Beloglazov
 * @since CloudSim Toolkit 1.0
 */
public abstract class BwProvisioner {

    /**
     * The total bandwidth capacity from the host that the provisioner can allocate to VMs.
     */
    private long bw;

    /**
     * The available bandwidth.
     */
    private long availableBw;

    /**
     * Creates the new BwProvisioner.
     *
     * @param bw The total bandwidth capacity from the host that the provisioner can allocate to VMs.
     * @pre bw >= 0
     * @post $none
     */
    public BwProvisioner(long bw) {
        setBw(bw);
        setAvailableBw(bw);
    }

    /**
     * Allocates BW for a given VM.
     *
     * @param vm the virtual machine for which the bw are being allocated
     * @param bw the bw to be allocated to the VM
     * @return $true if the bw could be allocated; $false otherwise
     * @pre $none
     * @post $none
     */
    public abstract boolean allocateBwForVm(Vm vm, long bw);

    /**
     * Gets the allocated BW for VM.
     *
     * @param vm the VM
     * @return the allocated BW for vm
     */
    public abstract long getAllocatedBwForVm(Vm vm);

    /**
     * Releases BW used by a VM.
     *
     * @param vm the vm
     * @pre $none
     * @post none
     */
    public abstract void deallocateBwForVm(Vm vm);

    /**
     * Releases BW used by all VMs.
     *
     * @pre $none
     * @post none
     */
    public void deallocateBwForAllVms() {
        setAvailableBw(getBw());
    }

    /**
     * Checks if it is possible to change the current allocated BW for the VM
     * to a new amount, depending on the available BW.
     *
     * @param vm the vm to check if there is enough available BW on the host to
     *           change the VM allocated BW
     * @param bw the new total amount of BW for the VM.
     * @return true, if is suitable for vm
     */
    public abstract boolean isSuitableForVm(Vm vm, long bw);

    /**
     * Gets the bw capacity.
     *
     * @return the bw capacity
     */
    public long getBw() {
        return bw;
    }

    /**
     * Sets the bw capacity.
     *
     * @param bw the new bw capacity
     */
    protected void setBw(long bw) {
        this.bw = bw;
    }

    /**
     * Gets the available BW in the host.
     *
     * @return available bw
     * @pre $none
     * @post $none
     */
    public long getAvailableBw() {
        return availableBw;
    }

    /**
     * Gets the amount of used BW in the host.
     *
     * @return used bw
     * @pre $none
     * @post $none
     */
    public long getUsedBw() {
        return bw - availableBw;
    }

    /**
     * Sets the available bw.
     *
     * @param availableBw the new available bw
     */
    protected void setAvailableBw(long availableBw) {
        this.availableBw = availableBw;
    }

}
